package Tech.yunjing.onlineStorage.controller;

import Tech.yunjing.onlineStorage.common.utils.BaseResult;
import Tech.yunjing.onlineStorage.common.utils.Constants;
import Tech.yunjing.onlineStorage.handler.FileHandler;
import Tech.yunjing.onlineStorage.module.TechFile;
import Tech.yunjing.onlineStorage.service.ResourcesService;
import Tech.yunjing.onlineStorage.service.TechFileService;
import com.wordnik.swagger.annotations.*;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.*;

/**
 * Created by lenovo on 2016/6/27.
 */
@RequestMapping("${server_url}/file")
@RestController
@Api(basePath = "api/file", value = "文件相关操作", description = "文件上传/下载/移动等", produces = "application/json")
public class FileController extends BaseController {

    @Value("${disk_path}")
    private String disk_path;
    @Value("${server_path}")
    private String server_path;
    @Value("${server_url}")
    private String server_url;

    @Autowired
    private TechFileService techFileService;

    Logger logger = Logger.getLogger(this.getClass());

    @ApiOperation(value="newFolder",notes="创建文件夹")
    //@ApiImplicitParams({@ApiImplicitParam(name = "parentId",dataType = "String"), @ApiImplicitParam(name = "name",dataType = "String")})
    @ApiResponses(value = {
            @ApiResponse(code = Constants.FAIL, message = "unknown server errors"),
            @ApiResponse(code = Constants.SUCCESS, message = "创建文成功") })
    @RequestMapping(value = "newFolder",method = RequestMethod.POST)
    public BaseResult newFolder(TechFile techFile) throws IOException {
        String parentPath = techFileService.findPath(techFile.getParentId());
        if(StringUtils.isEmpty(parentPath)){
            return sendResult(Constants.FAIL,"未找到文件夹");
        }
        techFileService.save(techFile,parentPath);
        return sendResult(Constants.SUCCESS,"创建成功");
    }


    @ApiOperation(value="upload",notes="上传资源文件")
    @ApiImplicitParams({ @ApiImplicitParam(name = "file",paramType = "formData",dataType = "File")})
    @ApiResponses(value = {
            @ApiResponse(code = Constants.FAIL, message = "unknown server errors"),
            @ApiResponse(code = Constants.SUCCESS, message = "上传成功") })
    @RequestMapping(value = "upload/{folderId}",method = RequestMethod.POST)
    @ResponseBody
    public BaseResult upload(HttpServletRequest request,@PathVariable String folderId) throws IOException {
        String folderPath = techFileService.findPath(folderId);
        if(StringUtils.isEmpty(folderPath)){
            return sendResult(Constants.FAIL,"上传文件失败，无法找打文件夹");
        }
        //创建一个通用的多部分解析器
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        //判断 request 是否有文件上传,即多部分请求
        List<Map<String,Object>> fileList = new ArrayList<Map<String,Object>>();
        if(multipartResolver.isMultipart(request)) {
            //转换成多部分request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            //取得request中的所有文件名
            Iterator<String> iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                //记录上传过程起始时的时间，用来计算上传时间
                int pre = (int) System.currentTimeMillis();
                //取得上传文件
                MultipartFile file = multiRequest.getFile(iter.next());
                if (file != null) {
                    //取得当前上传文件的文件名称
                    String myFileName = file.getOriginalFilename();
                    String fileType = file.getContentType();
                    //如果名称不为“”,说明该文件存在，否则说明该文件不存在
                    if (myFileName.trim() != "") {
                        logger.debug(myFileName);
                        Map<String,Object> fileInfo = new HashMap<String, Object>();
                        //重命名上传后的文件名
                        //定义上传路径
                        File diskFile = new File(disk_path+folderPath);
                        if(!diskFile.exists()){
                            diskFile.mkdir();
                        }
                        String type = myFileName.substring(myFileName.lastIndexOf("."));
                        String realName = UUID.randomUUID().toString().replace("-","");
                        String path = disk_path +folderPath+realName+type;
                        File localFile = new File(path);
                        file.transferTo(localFile);
                        //upload success save record
                        TechFile techFile = new TechFile();
                        techFile.setId(UUID.randomUUID().toString());
                        techFile.setName(myFileName.substring(0,myFileName.lastIndexOf(".")));
                        techFile.setPath(folderPath+realName+type);
                        techFile.setParentId(folderId);
                        techFile.setCreateDate(new Date());
                        techFile.setUpdateDate(new Date());
                        techFile.setType(type);
                        techFileService.save(techFile);
                        fileInfo.put("id",techFile.getId());
                        fileInfo.put("url",server_path+server_url+"/file/download/"+techFile.getId());
                        fileInfo.put("name",techFile.getName());
                        fileList.add(fileInfo);
                    }
                }
                //记录上传该文件后的时间
                int finaltime = (int) System.currentTimeMillis();

            }
        }
        return sendResult(Constants.SUCCESS,"上传成功",fileList);
    }

    @ApiOperation(value="download",notes="下载资源文件,使用浏览器测试下载")
    @RequestMapping(value = "download/{id}",method = RequestMethod.GET)
    public ResponseEntity<byte[]> download(@PathVariable String id) throws IOException {
        TechFile techFile = techFileService.getById(id);
        if(null!=techFile){
            File file=new File(disk_path+techFile.getPath());
            HttpHeaders headers = new HttpHeaders();
            String fileName=new String((techFile.getName()+techFile.getType()).getBytes("UTF-8"),"iso-8859-1");//为了解决中文名称乱码问题
            headers.setContentDispositionFormData("attachment", fileName);
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
                    headers, HttpStatus.CREATED);
        }else{
            return null;
        }

    }

    @ApiOperation(value="delete",notes="删除资源文件")
    @ApiResponses(value = {
            @ApiResponse(code = Constants.FAIL, message = "unknown server errors"),
            @ApiResponse(code = Constants.SUCCESS, message = "删除成功") })
    @RequestMapping(value = "delete/{id}",method = RequestMethod.POST)
    public BaseResult delete(@PathVariable String id) throws IOException {
         String sqlPath = techFileService.findPath(id);
         if(!StringUtils.isEmpty(sqlPath)){
            boolean flag = FileHandler.delete(disk_path+sqlPath);
             if(flag){
                 techFileService.physicallyDelete(id);
                 return sendResult(Constants.SUCCESS,"删除成功");
             }
         }
        return sendResult(Constants.FAIL,"删除失败");
    }

    @ApiOperation(value="rename",notes="重命名资源文件")
    @ApiResponses(value = {
            @ApiResponse(code = Constants.FAIL, message = "unknown server errors"),
            @ApiResponse(code = Constants.SUCCESS, message = "重命名成功") })
    @RequestMapping(value = "rename",method = RequestMethod.POST)
    public BaseResult rename(TechFile techFile) throws IOException {
        boolean flag = techFileService.rename(techFile);
        if(flag){
            return sendResult(Constants.SUCCESS,"重命名成功");
        }else{
            return sendResult(Constants.FAIL,"重命名成功");
        }

    }

    @ApiOperation(value="move",notes="移动资源文件")
    @ApiResponses(value = {
            @ApiResponse(code = Constants.FAIL, message = "unknown server errors"),
            @ApiResponse(code = Constants.SUCCESS, message = "移动成功") })
    @RequestMapping(value = "move",method = RequestMethod.POST)
    public BaseResult rename(String resourceId,String fromId,String targetId) throws IOException {
        TechFile target = techFileService.getById(targetId);
        if(null!=target){
            if(!target.getType().equals(Constants.RESOURCE_TYPE_FOLDER)){
                return sendResult(Constants.FAIL,"目标资源不是文件夹");
            }else{
                boolean flag = techFileService.move(resourceId,fromId,targetId);
                return sendResult(Constants.SUCCESS,"移动成功");
            }
        }else{
            return sendResult(Constants.FAIL,"未找到目标资源目录");
        }
    }

}
